﻿////////////////////////////////////////////////////////////////////////////////////////////////////
//
//  © 2012 Stanislav S. Yarmonov.
//
//  TODO:LICENSE
//     
////////////////////////////////////////////////////////////////////////////////////////////////////
using System;
using System.IO;
using System.Data;
using Pandora.IO;

namespace Pandora.Data
{
    ////////////////////////////////////////////////////////////////////////////////////////////////
    /// <summary>
    /// Extensions for IDbCommand interface.
    /// </summary>
    ////////////////////////////////////////////////////////////////////////////////////////////////
    public static class IDbCommandExtensions
    {
        #region -- Connection ----------------------------------------------------------------------
        ////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>
        /// Setup connection for command using connection string.
        /// </summary>
        /// <param name="command">
        /// Database command to be extended.
        /// </param>
        /// <param name="connectionString">
        /// Connection string to set for command.
        /// </param>
        /// <returns>
        /// Returns command for fluent coding.
        /// </returns>
        ////////////////////////////////////////////////////////////////////////////////////////////
        public static IDbCommand Connection(this IDbCommand command, string connectionString)
        {
            command.Connection.ConnectionString = connectionString;
            return command;
        }
        #endregion ---------------------------------------------------------------------------------

        #region -- Parameter -----------------------------------------------------------------------
        ////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>
        /// Add input parameter for database command.
        /// </summary>
        /// <param name="command">
        /// Database command, to be extended.
        /// </param>
        /// <param name="name">
        /// Database command parameter name.
        /// </param>
        /// <param name="type">
        /// Database command parameter type.
        /// </param>
        /// <param name="size">
        /// Database command parameter value size.
        /// </param>
        /// <param name="value">
        /// Database command parameter value.
        /// </param>
        /// <returns>
        /// Returns database command for fluent coding.
        /// </returns>
        ////////////////////////////////////////////////////////////////////////////////////////////
        public static IDbCommand Parameter(
            this IDbCommand command,
            string name,
            DbType type,
            int size,
            object value
        )
        {
            IDbDataParameter parameter = command.CreateParameter();
            command.Parameters.Add(parameter);

            parameter.DbType = type;
            parameter.ParameterName = name;
            parameter.Direction = ParameterDirection.Input;
            parameter.Size = size;
            parameter.Value = value == null ? DBNull.Value : value;

            return command;
        }

        ////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>
        /// Add output parameter for database command.
        /// </summary>
        /// <param name="command">
        /// Database command, to be extended.
        /// </param>
        /// <param name="name">
        /// Database command parameter name.
        /// </param>
        /// <param name="type">
        /// Database command parameter type.
        /// </param>
        /// <param name="size">
        /// Database command parameter value size.
        /// </param>
        /// <param name="parameter">
        /// Database parameter variable for output.
        /// </param>
        /// <returns>
        /// Returns database command for fluent coding.
        /// </returns>
        ////////////////////////////////////////////////////////////////////////////////////////////
        public static IDbCommand Parameter(
            this IDbCommand command,
            string name,
            DbType type,
            int size,
            out IDbDataParameter parameter
        )
        {
            parameter = command.CreateParameter();
            command.Parameters.Add(parameter);

            parameter.DbType = type;
            parameter.ParameterName = name;
            parameter.Direction = ParameterDirection.Output;
            parameter.Size = size;

            return command;
        }

        ////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>
        /// Add input/output parameter for database command.
        /// </summary>
        /// <param name="command">
        /// Database command, to be extended.
        /// </param>
        /// <param name="name">
        /// Database command parameter name.
        /// </param>
        /// <param name="type">
        /// Database command parameter type.
        /// </param>
        /// <param name="size">
        /// Database command parameter value size.
        /// </param>
        /// <param name="value">
        /// Database command parameter value.
        /// </param>
        /// <param name="parameter">
        /// Database parameter variable for output.
        /// </param>
        /// <returns>
        /// Returns database command for fluent coding.
        /// </returns>
        ////////////////////////////////////////////////////////////////////////////////////////////
        public static IDbCommand Parameter(
            this IDbCommand command,
            string name,
            DbType type,
            int size,
            object value,
            out IDbDataParameter parameter
        )
        {
            parameter = command.CreateParameter();
            command.Parameters.Add(parameter);

            parameter.DbType = type;
            parameter.ParameterName = name;
            parameter.Direction = ParameterDirection.InputOutput;
            parameter.Size = size;
            parameter.Value = value == null ? DBNull.Value : value;

            return command;
        }
        #endregion ---------------------------------------------------------------------------------

        #region -- UInt8 ---------------------------------------------------------------------------
        ////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>
        /// Add byte input parameter for database command.
        /// </summary>
        /// <param name="command">
        /// Database command, to be extended.
        /// </param>
        /// <param name="name">
        /// Database command parameter name.
        /// </param>
        /// <param name="value">
        /// Database command parameter value.
        /// </param>
        /// <returns>
        /// Returns database command for fluent coding.
        /// </returns>
        ////////////////////////////////////////////////////////////////////////////////////////////
        public static IDbCommand UInt8(this IDbCommand command, string name, byte? value)
        {
            return command.Parameter(name, DbType.Byte, 0, value);
        }

        ////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>
        /// Add byte output parameter for database command.
        /// </summary>
        /// <param name="command">
        /// Database command, to be extended.
        /// </param>
        /// <param name="name">
        /// Database command parameter name.
        /// </param>
        /// <param name="parameter">
        /// Database parameter variable for output.
        /// </param>
        /// <returns>
        /// Returns database command for fluent coding.
        /// </returns>
        ////////////////////////////////////////////////////////////////////////////////////////////
        public static IDbCommand UInt8(this IDbCommand command, string name, out IDbDataParameter parameter)
        {
            return command.Parameter(name, DbType.Byte, 0, out parameter);
        }

        ////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>
        /// Add byte input/output parameter for database command.
        /// </summary>
        /// <param name="command">
        /// Database command, to be extended.
        /// </param>
        /// <param name="name">
        /// Database command parameter name.
        /// </param>
        /// <param name="value">
        /// Database command parameter value.
        /// </param>
        /// <param name="parameter">
        /// Database parameter variable for output.
        /// </param>
        /// <returns>
        /// Returns database command for fluent coding.
        /// </returns>
        ////////////////////////////////////////////////////////////////////////////////////////////
        public static IDbCommand UInt8(this IDbCommand command, string name, byte? value, out IDbDataParameter parameter)
        {
            return command.Parameter(name, DbType.Byte, 0, value, out parameter);
        }
        #endregion ---------------------------------------------------------------------------------

        #region -- Int16 ---------------------------------------------------------------------------
        ////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>
        /// Add Int16 input parameter for database command.
        /// </summary>
        /// <param name="command">
        /// Database command, to be extended.
        /// </param>
        /// <param name="name">
        /// Database command parameter name.
        /// </param>
        /// <param name="value">
        /// Database command parameter value.
        /// </param>
        /// <returns>
        /// Returns database command for fluent coding.
        /// </returns>
        ////////////////////////////////////////////////////////////////////////////////////////////
        public static IDbCommand Int16(this IDbCommand command, string name, Int16? value)
        {
            return command.Parameter(name, DbType.Int16, 0, value);
        }

        ////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>
        /// Add Int16 output parameter for database command.
        /// </summary>
        /// <param name="command">
        /// Database command, to be extended.
        /// </param>
        /// <param name="name">
        /// Database command parameter name.
        /// </param>
        /// <param name="parameter">
        /// Database parameter variable for output.
        /// </param>
        /// <returns>
        /// Returns database command for fluent coding.
        /// </returns>
        ////////////////////////////////////////////////////////////////////////////////////////////
        public static IDbCommand Int16(this IDbCommand command, string name, out IDbDataParameter parameter)
        {
            return command.Parameter(name, DbType.Int16, 0, out parameter);
        }

        ////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>
        /// Add Int16 input/output parameter for database command.
        /// </summary>
        /// <param name="command">
        /// Database command, to be extended.
        /// </param>
        /// <param name="name">
        /// Database command parameter name.
        /// </param>
        /// <param name="value">
        /// Database command parameter value.
        /// </param>
        /// <param name="parameter">
        /// Database parameter variable for output.
        /// </param>
        /// <returns>
        /// Returns database command for fluent coding.
        /// </returns>
        ////////////////////////////////////////////////////////////////////////////////////////////
        public static IDbCommand Int16(this IDbCommand command, string name, Int16? value, out IDbDataParameter parameter)
        {
            return command.Parameter(name, DbType.Int16, 0, value, out parameter);
        }
        #endregion ---------------------------------------------------------------------------------

        #region -- Int32 ---------------------------------------------------------------------------
        ////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>
        /// Add Int32 input parameter for database command.
        /// </summary>
        /// <param name="command">
        /// Database command, to be extended.
        /// </param>
        /// <param name="name">
        /// Database command parameter name.
        /// </param>
        /// <param name="value">
        /// Database command parameter value.
        /// </param>
        /// <returns>
        /// Returns database command for fluent coding.
        /// </returns>
        ////////////////////////////////////////////////////////////////////////////////////////////
        public static IDbCommand Int32(this IDbCommand command, string name, Int32? value)
        {
            return command.Parameter(name, DbType.Int32, 0, value);
        }

        ////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>
        /// Add Int32 output parameter for database command.
        /// </summary>
        /// <param name="command">
        /// Database command, to be extended.
        /// </param>
        /// <param name="name">
        /// Database command parameter name.
        /// </param>
        /// <param name="parameter">
        /// Database parameter variable for output.
        /// </param>
        /// <returns>
        /// Returns database command for fluent coding.
        /// </returns>
        ////////////////////////////////////////////////////////////////////////////////////////////
        public static IDbCommand Int32(this IDbCommand command, string name, out IDbDataParameter parameter)
        {
            return command.Parameter(name, DbType.Int32, 0, out parameter);
        }

        ////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>
        /// Add Int32 input/output parameter for database command.
        /// </summary>
        /// <param name="command">
        /// Database command, to be extended.
        /// </param>
        /// <param name="name">
        /// Database command parameter name.
        /// </param>
        /// <param name="value">
        /// Database command parameter value.
        /// </param>
        /// <param name="parameter">
        /// Database parameter variable for output.
        /// </param>
        /// <returns>
        /// Returns database command for fluent coding.
        /// </returns>
        ////////////////////////////////////////////////////////////////////////////////////////////
        public static IDbCommand Int32(this IDbCommand command, string name, Int32? value, out IDbDataParameter parameter)
        {
            return command.Parameter(name, DbType.Int32, 0, value, out parameter);
        }
        #endregion ---------------------------------------------------------------------------------

        #region -- Int64 ---------------------------------------------------------------------------
        ////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>
        /// Add Int64 input parameter for database command.
        /// </summary>
        /// <param name="command">
        /// Database command, to be extended.
        /// </param>
        /// <param name="name">
        /// Database command parameter name.
        /// </param>
        /// <param name="value">
        /// Database command parameter value.
        /// </param>
        /// <returns>
        /// Returns database command for fluent coding.
        /// </returns>
        ////////////////////////////////////////////////////////////////////////////////////////////
        public static IDbCommand Int64(this IDbCommand command, string name, Int64? value)
        {
            return command.Parameter(name, DbType.Int64, 0, value);
        }

        ////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>
        /// Add Int64 output parameter for database command.
        /// </summary>
        /// <param name="command">
        /// Database command, to be extended.
        /// </param>
        /// <param name="name">
        /// Database command parameter name.
        /// </param>
        /// <param name="parameter">
        /// Database parameter variable for output.
        /// </param>
        /// <returns>
        /// Returns database command for fluent coding.
        /// </returns>
        ////////////////////////////////////////////////////////////////////////////////////////////
        public static IDbCommand Int64(this IDbCommand command, string name, out IDbDataParameter parameter)
        {
            return command.Parameter(name, DbType.Int64, 0, out parameter);
        }

        ////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>
        /// Add Int64 input/output parameter for database command.
        /// </summary>
        /// <param name="command">
        /// Database command, to be extended.
        /// </param>
        /// <param name="name">
        /// Database command parameter name.
        /// </param>
        /// <param name="value">
        /// Database command parameter value.
        /// </param>
        /// <param name="parameter">
        /// Database parameter variable for output.
        /// </param>
        /// <returns>
        /// Returns database command for fluent coding.
        /// </returns>
        ////////////////////////////////////////////////////////////////////////////////////////////
        public static IDbCommand Int64(this IDbCommand command, string name, Int64? value, out IDbDataParameter parameter)
        {
            return command.Parameter(name, DbType.Int64, 0, value, out parameter);
        }
        #endregion ---------------------------------------------------------------------------------

        #region -- Guid ----------------------------------------------------------------------------
        ////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>
        /// Add Guid input parameter for database command.
        /// </summary>
        /// <param name="command">
        /// Database command, to be extended.
        /// </param>
        /// <param name="name">
        /// Database command parameter name.
        /// </param>
        /// <param name="value">
        /// Database command parameter value.
        /// </param>
        /// <returns>
        /// Returns database command for fluent coding.
        /// </returns>
        ////////////////////////////////////////////////////////////////////////////////////////////
        public static IDbCommand Guid(this IDbCommand command, string name, Guid? value)
        {
            return command.Parameter(name, DbType.Guid, 0, value);
        }

        ////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>
        /// Add Guid output parameter for database command.
        /// </summary>
        /// <param name="command">
        /// Database command, to be extended.
        /// </param>
        /// <param name="name">
        /// Database command parameter name.
        /// </param>
        /// <param name="parameter">
        /// Database parameter variable for output.
        /// </param>
        /// <returns>
        /// Returns database command for fluent coding.
        /// </returns>
        ////////////////////////////////////////////////////////////////////////////////////////////
        public static IDbCommand Guid(this IDbCommand command, string name, out IDbDataParameter parameter)
        {
            return command.Parameter(name, DbType.Guid, 0, out parameter);
        }

        ////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>
        /// Add Guid input/output parameter for database command.
        /// </summary>
        /// <param name="command">
        /// Database command, to be extended.
        /// </param>
        /// <param name="name">
        /// Database command parameter name.
        /// </param>
        /// <param name="value">
        /// Database command parameter value.
        /// </param>
        /// <param name="parameter">
        /// Database parameter variable for output.
        /// </param>
        /// <returns>
        /// Returns database command for fluent coding.
        /// </returns>
        ////////////////////////////////////////////////////////////////////////////////////////////
        public static IDbCommand Guid(this IDbCommand command, string name, Guid? value, out IDbDataParameter parameter)
        {
            return command.Parameter(name, DbType.Guid, 0, value, out parameter);
        }
        #endregion ---------------------------------------------------------------------------------

        #region -- ANSI text -----------------------------------------------------------------------
        ////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>
        /// Add ANSI text input parameter for database command.
        /// </summary>
        /// <param name="command">
        /// Database command, to be extended.
        /// </param>
        /// <param name="name">
        /// Database command parameter name.
        /// </param>
        /// <param name="value">
        /// Database command parameter value.
        /// </param>
        /// <returns>
        /// Returns database command for fluent coding.
        /// </returns>
        ////////////////////////////////////////////////////////////////////////////////////////////
        public static IDbCommand Ansi(this IDbCommand command, string name, string value)
        {
            return command.Parameter(name, DbType.AnsiString, 0, value);
        }

        ////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>
        /// Add ANSI text output parameter for database command.
        /// </summary>
        /// <param name="command">
        /// Database command, to be extended.
        /// </param>
        /// <param name="name">
        /// Database command parameter name.
        /// </param>
        /// <param name="length">
        /// ANSI string length.
        /// </param>
        /// <param name="parameter">
        /// Database parameter variable for output.
        /// </param>
        /// <returns>
        /// Returns database command for fluent coding.
        /// </returns>
        ////////////////////////////////////////////////////////////////////////////////////////////
        public static IDbCommand Ansi(this IDbCommand command, string name, int length, out IDbDataParameter parameter)
        {
            return command.Parameter(name, DbType.AnsiString, length, out parameter);
        }

        ////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>
        /// Add ANSI text input/output parameter for database command.
        /// </summary>
        /// <param name="command">
        /// Database command, to be extended.
        /// </param>
        /// <param name="name">
        /// Database command parameter name.
        /// </param>
        /// <param name="value">
        /// Database command parameter value.
        /// </param>
        /// <param name="parameter">
        /// Database parameter variable for output.
        /// </param>
        /// <returns>
        /// Returns database command for fluent coding.
        /// </returns>
        ////////////////////////////////////////////////////////////////////////////////////////////
        public static IDbCommand Ansi(this IDbCommand command, string name, string value, out IDbDataParameter parameter)
        {
            return command.Parameter(name, DbType.AnsiString, 0, value, out parameter);
        }
        #endregion ---------------------------------------------------------------------------------

        #region -- Unicode text --------------------------------------------------------------------
        ////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>
        /// Add Unicode text input parameter for database command.
        /// </summary>
        /// <param name="command">
        /// Database command, to be extended.
        /// </param>
        /// <param name="name">
        /// Database command parameter name.
        /// </param>
        /// <param name="value">
        /// Database command parameter value.
        /// </param>
        /// <returns>
        /// Returns database command for fluent coding.
        /// </returns>
        ////////////////////////////////////////////////////////////////////////////////////////////
        public static IDbCommand Unicode(this IDbCommand command, string name, string value)
        {
            return command.Parameter(name, DbType.String, 0, value);
        }

        ////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>
        /// Add Unicode text output parameter for database command.
        /// </summary>
        /// <param name="command">
        /// Database command, to be extended.
        /// </param>
        /// <param name="name">
        /// Database command parameter name.
        /// </param>
        /// <param name="parameter">
        /// Database parameter variable for output.
        /// </param>
        /// <returns>
        /// Returns database command for fluent coding.
        /// </returns>
        ////////////////////////////////////////////////////////////////////////////////////////////
        public static IDbCommand Unicode(this IDbCommand command, string name, out IDbDataParameter parameter)
        {
            return command.Parameter(name, DbType.String, 0, out parameter);
        }

        ////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>
        /// Add Unicode text input/output parameter for database command.
        /// </summary>
        /// <param name="command">
        /// Database command, to be extended.
        /// </param>
        /// <param name="name">
        /// Database command parameter name.
        /// </param>
        /// <param name="value">
        /// Database command parameter value.
        /// </param>
        /// <param name="parameter">
        /// Database parameter variable for output.
        /// </param>
        /// <returns>
        /// Returns database command for fluent coding.
        /// </returns>
        ////////////////////////////////////////////////////////////////////////////////////////////
        public static IDbCommand Unicode(this IDbCommand command, string name, string value, out IDbDataParameter parameter)
        {
            return command.Parameter(name, DbType.String, 0, value, out parameter);
        }
        #endregion ---------------------------------------------------------------------------------

        #region -- XML -----------------------------------------------------------------------------
        ////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>
        /// Add XML input parameter for database command.
        /// </summary>
        /// <param name="command">
        /// Database command, to be extended.
        /// </param>
        /// <param name="name">
        /// Database command parameter name.
        /// </param>
        /// <param name="value">
        /// Database command parameter value.
        /// </param>
        /// <returns>
        /// Returns database command for fluent coding.
        /// </returns>
        ////////////////////////////////////////////////////////////////////////////////////////////
        public static IDbCommand Xml(this IDbCommand command, string name, string value)
        {
            return command.Parameter(name, DbType.Xml, 0, value);
        }

        ////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>
        /// Add XML output parameter for database command.
        /// </summary>
        /// <param name="command">
        /// Database command, to be extended.
        /// </param>
        /// <param name="name">
        /// Database command parameter name.
        /// </param>
        /// <param name="parameter">
        /// Database parameter variable for output.
        /// </param>
        /// <returns>
        /// Returns database command for fluent coding.
        /// </returns>
        ////////////////////////////////////////////////////////////////////////////////////////////
        public static IDbCommand Xml(this IDbCommand command, string name, out IDbDataParameter parameter)
        {
            return command.Parameter(name, DbType.Xml, 0, out parameter);
        }

        ////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>
        /// Add XML input/output parameter for database command.
        /// </summary>
        /// <param name="command">
        /// Database command, to be extended.
        /// </param>
        /// <param name="name">
        /// Database command parameter name.
        /// </param>
        /// <param name="value">
        /// Database command parameter value.
        /// </param>
        /// <param name="parameter">
        /// Database parameter variable for output.
        /// </param>
        /// <returns>
        /// Returns database command for fluent coding.
        /// </returns>
        ////////////////////////////////////////////////////////////////////////////////////////////
        public static IDbCommand Xml(this IDbCommand command, string name, string value, out IDbDataParameter parameter)
        {
            return command.Parameter(name, DbType.Xml, 0, value, out parameter);
        }
        #endregion ---------------------------------------------------------------------------------

        #region -- Binary --------------------------------------------------------------------------
        ////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>
        /// Add varbinary input parameter for database command.
        /// </summary>
        /// <param name="command">
        /// Database command, to be extended.
        /// </param>
        /// <param name="name">
        /// Database command parameter name.
        /// </param>
        /// <param name="value">
        /// Database command parameter value.
        /// </param>
        /// <returns>
        /// Returns database command for fluent coding.
        /// </returns>
        ////////////////////////////////////////////////////////////////////////////////////////////
        public static IDbCommand Binary(this IDbCommand command, string name, Stream value)
        {
            return command.Parameter(name, DbType.Binary, 0, value.AsBytes());
        }
        ////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>
        /// Add varbinary input parameter for database command.
        /// </summary>
        /// <param name="command">
        /// Database command, to be extended.
        /// </param>
        /// <param name="name">
        /// Database command parameter name.
        /// </param>
        /// <param name="value">
        /// Database command parameter value.
        /// </param>
        /// <returns>
        /// Returns database command for fluent coding.
        /// </returns>
        ////////////////////////////////////////////////////////////////////////////////////////////
        public static IDbCommand Binary(this IDbCommand command, string name, byte[] value)
        {
            return command.Parameter(name, DbType.Binary, 0, value);
        }
        #endregion ---------------------------------------------------------------------------------

        #region -- Execution routines --------------------------------------------------------------
        ////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>
        /// Database command execution routine.
        /// </summary>
        /// <param name="command">
        /// Database command, to be extended.
        /// </param>
        /// <param name="handlers">
        /// Handlers, one for each returned recordser in the order recordsets are returned.
        /// </param>
        /// <returns>
        /// Returns database command for fluent coding.
        /// </returns>
        ////////////////////////////////////////////////////////////////////////////////////////////
        public static IDbCommand Execute(this IDbCommand command, params Action<IDataReader>[] handlers)
        {
            command.Connection.Open();

            try
            {
                if (handlers.Length == 0)
                {
                    command.ExecuteNonQuery();
                }
                else
                {
                    using (IDataReader reader = command.ExecuteReader())
                    {
                        for (int index = 0; index < handlers.Length; index++)
                        {
                            if (index > 0)
                            {
                                reader.NextResult();
                            }

                            handlers[index](reader);
                        }
                    }
                }
            }
            finally
            {
                command.Connection.Close();
            }

            return command;
        }

        ////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>
        /// Checks if the database command returns any records.
        /// </summary>
        /// <param name="command">
        /// Database command, to be extended.
        /// </param>
        /// <returns>
        /// Returns true if at least one record exists and false otherwise.
        /// </returns>
        ////////////////////////////////////////////////////////////////////////////////////////////
        public static bool Exists(this IDbCommand command)
        {
            bool result = false;

            command.Connection.Open();

            try
            {
                using (IDataReader reader = command.ExecuteReader())
                {
                    result = reader.Read();
                }
            }
            finally
            {
                command.Connection.Close();
            }

            return result;
        }
        #endregion ---------------------------------------------------------------------------------
    }
}
